﻿using System;
using System.Collections.Generic;
using System.Linq;
using Se.Framework.Common;
using Rhino.Mocks;
using Se.Framework.Common.Data;

namespace Se.Framework.Test
{
    public class TestBase
    {
        /// <summary>
        /// Generates an stub using Rhinomocks and register it.
        /// </summary>
        /// <typeparam name="T">Type of the stub to be created</typeparam>
        /// <returns>The object created</returns>
        public static T Mock<T>() where T : class
        {
            if (ObjectRegistry.Current.IsRegistered<T>())
            {
                ObjectRegistry.Current.Clean(ObjectRegistry.Current.Resolve<T>());
            }

            T stub = MockRepository.GenerateStub<T>();
            ObjectRegistry.Current.RegisterInstance(typeof(T), stub);

            return stub;
        }

        /// <summary>
        /// Generates an stub using Rhinomocks and register it with an specific name.
        /// </summary>
        /// <typeparam name="T">Type of the stub to be created</typeparam>
        /// <param name="name">Nmae of the registered Stub</param>
        /// <returns>The object created</returns>
        public static T Mock<T>(string name) where T : class
        {
            if (ObjectRegistry.Current.IsRegistered<T>(name))
            {
                ObjectRegistry.Current.Clean(ObjectRegistry.Current.Resolve<T>(name));
            }

            T stub = MockRepository.GenerateStub<T>();
            ObjectRegistry.Current.RegisterInstance(typeof(T), name, stub);

            return stub;
        }

        /// <summary>
        /// Generates an stub for a repository, add data to it and 
        /// returns an IQueryable for the Query method
        /// </summary>
        /// <typeparam name="T">Type of the repository to be created</typeparam>
        /// <param name="data">Entities to be added to the repository</param>
        /// <returns>IRepository<T></returns>
        public static IRepository<T> MockRepo<T>(IEnumerable<T> data) where T : class
        {
            var repository = Mock<IRepository<T>>();
            repository.Expect(r => r.Query()).Return(data.AsQueryable());

            return repository;
        }
    }
}
